package com.ruyuan.eshop.framework.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.*;
import com.ruyuan.eshop.framework.core.ObjectMapperImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.*;

/**
 * <p>
 * Json对象转换工具
 * </p>
 *
 * @author pwd
 * @version 1.0
 */
@Slf4j
public class JsonUtil {

	private static final ObjectMapper objectMapper = new ObjectMapperImpl();

	/**
	 * 单个对象转json字符串
	 * @param o
	 * @return
	 */
	public static String object2Json(Object o) {
		if (o == null) {
			return null;
		}

		String s = null;
		try {
			s = objectMapper.writeValueAsString(o);
		} catch (Exception e) {
			log.warn("object to json error", e);
		}
		return s;
	}

	/**
	 * 集合对象批量转json字符串集合
	 * @param objects
	 * @param <T>
	 * @return
	 */
	public static <T> List<String> listObject2ListJson(List<T> objects) {
		if (objects == null) {
			return null;
		}

		List<String> lists = new ArrayList<String>();
		for (T t : objects) {
			lists.add(object2Json(t));
		}

		return lists;
	}

	/**
	 * json字符串集合批量转对象集合
	 * @param jsons
	 * @param clazz
	 * @param <T>
	 * @return
	 */
	public static <T> List<T> listJson2ListObject(List<String> jsons, Class<T> clazz) {
		if (jsons == null) {
			return null;
		}

		List<T> ts = new ArrayList<T>();
		for (String j : jsons) {
			ts.add(json2Object(j, clazz));
		}

		return ts;
	}

	/**
	 * json字符串转指定类型的对象
	 * @param json
	 * @param clazz
	 * @param <T>
	 * @return
	 */
	public static <T> T json2Object(String json, Class<T> clazz) {
		if (!StringUtils.hasLength(json)) {
			return null;
		}

		try {
			return objectMapper.readValue(json, clazz);
		} catch (Exception e) {
			log.warn("json to object error", e);
		}
		return null;
	}

	/**
	 * json字符串转指定类型的对象
	 * @param json
	 * @param typeReference
	 * @param <T>
	 * @return
	 */
	public static <T> T json2Object(String json, TypeReference<T> typeReference) {
		if (!StringUtils.hasLength(json)) {
			return null;
		}
		try {
			return objectMapper.readValue(json, typeReference);
		} catch (Exception e) {
			log.warn("json to object error", e);
		}
		return null;
	}

	/**
	 *  用于支持获取远程调用返回数据的转换
	 *  注意事项：
	 *      支持多单词下划线专驼峰（序列化和反序列化）
	 *
	 *
	 * @param clazz
	 * @param <T>
	 * @return
	 */
	public <T> T getData(Object data, Class<T> clazz){
		if(data == null) {
			return null;
		}
		try {
			String jsonStr = objectMapper.writeValueAsString(data);
			return objectMapper.readValue(jsonStr, clazz);
		} catch (JsonProcessingException e) {
			log.warn("json data process error", e);
		}
		return null;
	}

	/**
	 *  用于支持获取远程调用返回数据的转换
	 *  注意事项：
	 *      支持多单词下划线专驼峰（序列化和反序列化）
	 *
	 *
	 * @param typeReference
	 * @param <T>
	 * @return
	 */
	public <T> T getData(Object data, TypeReference<T> typeReference){
		if(data == null) {
			return null;
		}
		try {
			String jsonStr = objectMapper.writeValueAsString(data);
			return objectMapper.readValue(jsonStr, typeReference);
		} catch (JsonProcessingException e) {
			log.warn("json data process error", e);
		}
		return null;
	}


	/**
	 * 把json格式的字符串转换为map对线
	 * @param json
	 * @return LinkedHashMap
	 */
	public static LinkedHashMap<String, Object> toMap(String json) {
		return toMap(parseJson(json));
	}

	/**
	 * 把json数组格式的字符串转换为 List
	 * @return List<Object>
	 */
	public static List<Map<String,Object>> toList(String jsonArr){

		List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
		JsonArray jsonArray = parseJsonArray(jsonArr);
		for (int i = 0; i < jsonArray.size(); i++) {
			Object value = jsonArray.get(i);
			Map<String,Object> map = toMap(value.toString());
			list.add(map);
		}
		return list;
	}


	public static String objectToJson(Object object){

		ObjectMapper mapper = new ObjectMapper();
		String jsonStr = "";
		try {
			jsonStr  = mapper.writeValueAsString(object);

		} catch (Exception e) {
			e.printStackTrace();
		}
		return jsonStr;
	}

	/**
	 * 获取JsonObject
	 *
	 * @param json
	 * @return
	 */
	private static JsonObject parseJson(String json) {
		JsonParser parser = new JsonParser();
		JsonObject jsonObj = parser.parse(json).getAsJsonObject();
		return jsonObj;
	}

	private static JsonArray parseJsonArray(String jsonArr){
		JsonParser parser = new JsonParser();
		JsonArray jsonArray = parser.parse(jsonArr).getAsJsonArray();
		return jsonArray;
	}

	/**
	 * 将JSONObjec对象转换成Map-List集合
	 *
	 * @param json
	 * @return
	 */
	private static LinkedHashMap<String, Object> toMap(JsonObject json) {
		LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
		Set<Map.Entry<String, JsonElement>> entrySet = json.entrySet();
		for (Iterator<Map.Entry<String, JsonElement>> iter = entrySet.iterator(); iter
				.hasNext();) {
			Map.Entry<String, JsonElement> entry = iter.next();
			String key = entry.getKey();
			Object value = entry.getValue();
			if (value instanceof JsonArray) {
				map.put(key, toList((JsonArray) value));
			} else if (value instanceof JsonObject) {
				map.put(key, toMap((JsonObject) value));
			} else if (value instanceof JsonNull) {
				map.put(key, "");
			} else {
				String str = value.toString();
				if (str.startsWith("\"")) {
					str = str.substring(1, str.length() - 1);
					Object obj = str;
					map.put(key, obj);
				} else {
					map.put(key, value);
				}

			}

		}
		return map;
	}

	/**
	 * 将JSONArray对象转换成List集合
	 *
	 * @param json
	 * @return
	 */
	private static List<Object> toList(JsonArray json) {
		List<Object> list = new ArrayList<Object>();
		for (int i = 0; i < json.size(); i++) {
			Object value = json.get(i);
			if (value instanceof JsonArray) {
				list.add(toList((JsonArray) value));
			} else if (value instanceof JsonObject) {
				list.add(toMap((JsonObject) value));
			} else if (value instanceof JsonNull) {
				list.add("");
			} else {
				String str = value.toString();
				if (str.startsWith("\"")) {
					str = str.substring(1, str.length() - 1);
					Object obj = str;
					list.add(obj);
				} else {
					list.add(value);
				}
			}
		}
		return list;
	}

	/**
	 * 将json字符串转成list
	 * @param jsonData
	 * @param clz
	 * @return
	 */
	public static <T> List<T> jsonToList(String jsonData,Class<T> clz){

		if (StringUtil.isEmpty(jsonData)) {
			return null;
		}

		ObjectMapper mapper = new ObjectMapper();

		JavaType javaType =  mapper.getTypeFactory().constructParametricType(ArrayList.class, clz);

		try {
			return mapper.readValue(jsonData, javaType);
		} catch (Exception e) {
			log.error("转换Object 异常",e);
		}

		return null;
	}

	/**
	 * 将json字符串转成Object
	 * @param jsonData
	 * @param clz
	 * @return
	 */
	public static <T> T jsonToObject(String jsonData,Class<T> clz){
		ObjectMapper mapper = new ObjectMapper();

		try {
			return mapper.readValue(jsonData,clz);
		} catch (IOException e) {
			log.error("转换Object 异常",e);
		}
		return null;
	}
}
